﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections.Specialized;
using System.Web;

namespace TathamOddie.OpenSearchValidator.Logic
{
	public static class XhtmlParser
	{
		static readonly IDictionary<string, Regex> TagExpressions = new Dictionary<string, Regex>();
		const string TagExpressionFormat = @"(?s:<{0}\s*(?<content>.*?)\s*?/?>)";
		const string TagExpressionContentGroup = "content";

		static readonly Regex AttributeExpression = new Regex(@"(?<name>\w*)=(?<quote>['""])(?<value>.*?)\k<quote>");
		const string AttributeExpressionNameGroup = "name";
		const string AttributeExpressionValueGroup = "value";

		private static Regex GetTagExpression(string tagName)
		{
			if (!TagExpressions.ContainsKey(tagName))
			{
				TagExpressions.Add(
					tagName,
					new Regex(string.Format(TagExpressionFormat, tagName))
				);
			}

			return TagExpressions[tagName];
		}

		public static XhtmlTag[] ParseTags(string html, string tagName)
		{
			var expression = GetTagExpression(tagName);
			var matches = expression.Matches(html);

			return matches.OfType<Match>().Select(m =>
				{
					var content = m.Groups[TagExpressionContentGroup].Value;

					var attributes = new NameValueCollection();
					
					var attributeMatches = AttributeExpression.Matches(content).OfType<Match>();
					foreach(var attributeMatch in attributeMatches)
					{
                        attributes.Add
						(
							HttpUtility.HtmlDecode(attributeMatch.Groups[AttributeExpressionNameGroup].Value),
							HttpUtility.HtmlDecode(attributeMatch.Groups[AttributeExpressionValueGroup].Value)
						);
					}

					return new XhtmlTag(tagName, attributes);
				}).ToArray();
		}
	}
}